﻿using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.IO;
using System.Linq;
using Labthink.PCSoft.UniversalHost4.Model.Setting;
using Labthink.PCSoft.UniversalHost4.Model.Unit;
using Labthink.PCSoft.UniversalHost4.Utility;
using NLog.Fluent;

namespace SystemSettings
{
    /// <summary>
    /// 配置文件设置和读取
    /// </summary>
    public class ConfigAndSettings
    {
        public static readonly string RootPath = AppDomain.CurrentDomain.BaseDirectory;
        public static readonly string IniFile = Path.Combine(RootPath, "Config\\AppConfig.ini");//主配置文件
        public static readonly string IdFile = Path.Combine(RootPath, "Config\\id.ini");//主配置文件
        public static readonly string UnitDb = Path.Combine(RootPath, "Config\\App.db");
        public static readonly string UnitPath = Path.Combine(RootPath, "Config\\Temp");//数据库模板路径，解压目标路径
        public static readonly string CustomPath = Path.Combine(RootPath, "CustomInfo");//自定义设置路径
        public static event EventHandler BaseInfoChanged;

        public const string UnitDir = @"Labthink\Units";//单位压缩文件默认存储路径

        public static void Recover()
        {
            try
            {
                if (Directory.Exists(UnitPath))
                {
                    string cu;
                    var temp = Path.Combine(RootPath, "Temp");
                    if (!Directory.Exists(temp))
                    {
                        Directory.CreateDirectory(temp);
                    }

                    var units = new DirectoryInfo(UnitPath).GetDirectories();
                    foreach (var unit in units)
                    {
                        cu = Path.Combine(temp, unit.Name);
                        var files = new DirectoryInfo(unit.FullName).GetFiles();
                        if (!files.Any(f => f.Name == "Unit.note"))
                        {
                            continue;
                        }

                        Directory.Move(unit.FullName, cu);
                    }

                    Directory.Delete(UnitPath, true);
                    Directory.CreateDirectory(UnitPath);

                    units = new DirectoryInfo(temp).GetDirectories();

                    foreach (var unit in units)
                    {
                        cu = Path.Combine(UnitPath, unit.Name);
                        Directory.Move(unit.FullName, cu);
                    }

                    Directory.Delete(temp);
                }

                if (Directory.Exists(CustomPath))
                    Directory.Delete(CustomPath, true);
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Write();
            }
        }

        protected static void OnBaseInfoChanged(EventArgs e)
        {
            EventHandler handler = BaseInfoChanged;
            handler?.Invoke(null, e);
        }

        /// <summary>
        /// 获取串口配置
        /// </summary>
        /// <returns></returns>
        public static ComInfo GetComInfo()
        {
            IniHelper.Filename = IniFile;
            IniHelper.SectionName = "com";

            try
            {
                Log.Debug().Message("获取串口配置").Write();
                var ci = new ComInfo
                {
                    PortName = IniHelper.GetIni("portName", "COM1"),
                    BaudRate = IniHelper.GetIni("baudRate", "9600").ToInt(),
                    DataBits = IniHelper.GetIni("dataBits", "8").ToInt(),
                    Parity = IniHelper.GetIni("parity", "None"),
                    StopBits = IniHelper.GetIni("stopBits", "1").ToInt(),
                    ReadTimeout = IniHelper.GetIni("readTimeout", "1").ToInt(),
                    SaveComData = IniHelper.GetIni("saveComData", "0").ToInt() == 1,
                };

                return ci;
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("读取串口信息失败").Write();
                return new ComInfo();
            }
        }

        /// <summary>
        /// 设置串口配置
        /// </summary>
        /// <param name="ci"></param>
        /// <returns></returns>
        public static int SetComInfo(ComInfo ci)
        {
            IniHelper.Filename = IniFile;
            IniHelper.SectionName = "com";
            try
            {
                IniHelper.SetIni("portName", ci.PortName);
                IniHelper.SetIni("baudRate", ci.BaudRate + "");
                IniHelper.SetIni("dataBits", ci.DataBits + "");
                IniHelper.SetIni("parity", ci.Parity);
                IniHelper.SetIni("stopBits", ci.StopBits + "");
                IniHelper.SetIni("readTimeout", ci.ReadTimeout + "");
                IniHelper.SetIni("saveComData", (ci.SaveComData ? 1 : 0) + "");
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("设置串口信息失败").Write();
                throw new BusinessException(LanguageManager.GetLanguageValue("ActionFail"));
            }

            return 0;
        }

        /// <summary>
        /// 获取试验配置
        /// </summary>
        /// <returns></returns>
        public static TestConfig GetTestConfig()
        {
            IniHelper.Filename = IniFile;
            IniHelper.SectionName = "testConfig";

            try
            {
                Log.Debug().Message("获取试验配置").Write();
                var cfg = new TestConfig
                {
                    Unit = IniHelper.GetIni("unit", "kPa"),
                    FlowRange = IniHelper.GetIni("flowRange", "10").ToDouble(),
                    FlowRangeFix = IniHelper.GetIni("flowRangeFix", "0.01").ToDouble(),
                    PressureDecimalPlace = IniHelper.GetIni("pressureDecimalPlace", "1").ToInt(),
                    DecayRateDecimalPlace = IniHelper.GetIni("decayRateDecimalPlace", "3").ToInt(),
                    FlowDecimalPlace = IniHelper.GetIni("flowDecimalPlace", "3").ToInt(),
                    Tare = IniHelper.GetIni("tare","0").ToInt() == 1,
                };

                return cfg;
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("读试验配置失败").Write();
                return new TestConfig();
            }
        }

        /// <summary>
        /// 设置试验配置
        /// </summary>
        /// <param name="cfg"></param>
        /// <returns></returns>
        public static int SetTestConfig(TestConfig cfg)
        {
            IniHelper.Filename = IniFile;
            IniHelper.SectionName = "testConfig";
            try
            {
                IniHelper.SetIni("unit", cfg.Unit);
                IniHelper.SetIni("flowRange", cfg.FlowRange.ToString());
                IniHelper.SetIni("tare", cfg.Tare ? "1" : "0");
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("设置试验配置失败").Write();
                throw new BusinessException(LanguageManager.GetLanguageValue("ActionFail"));
            }

            return 0;
        }

        /// <summary>
        /// 获取基本配置
        /// </summary>
        /// <returns></returns>
        public static BaseInfo GetBaseInfo()
        {
            IniHelper.Filename = IniFile;
            IniHelper.SectionName = "base";

            try
            {
                Log.Debug().Message("获取基本配置").Write();
                var bi = new BaseInfo
                {
                    DataShield = IniHelper.GetIni("datashield", "0") != "0",
                    Device = IniHelper.GetIni("device", "00"),
                    Gmp = IniHelper.GetIni("gmp", "0") != "0",
                    Plugin = IniHelper.GetIni("plugin", "0") != "0",
                    Sn = IniHelper.GetIni("sn", "001"),
                    Type = IniHelper.GetIni("type", "00"),
                    Unit = IniHelper.GetIni("unit", "0") != "0",
                    DefaultUnit = GetDefaultUnit(),
                    Year = IniHelper.GetIni("year", DateTime.Now.Year + ""),
                    LastTestId = GetTestId(),
                    Version = IniHelper.GetIni(IniFile, "base", "version", "0.0.0.0"),
                    AutoReport = IniHelper.GetIni("autoReport", "0") != "0"
                };

                string nameKey = SystemInfo.GetCurrentLocale().Contains("CN") ? "name.cn" : "name.en";
                bi.Name = IniHelper.GetIni(nameKey, "");

                return bi;
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("读取设备的基本信息失败").Write();
                return new BaseInfo();
            }
        }

        /// <summary>
        /// 设置基本配置
        /// </summary>
        /// <param name="bi"></param>
        /// <returns></returns>
        public static int SetBaseInfo(BaseInfo bi)
        {
            IniHelper.Filename = IniFile;
            IniHelper.SectionName = "base";
            try
            {
                if (SystemInfo.Locale.Contains("CN"))
                {
                    IniHelper.SetIni("name.cn", bi.Name);
                }
                else
                {
                    IniHelper.SetIni("name.en", bi.Name);
                }

                IniHelper.SetIni("datashield", bi.DataShield ? "1" : "0");

                IniHelper.SetIni("datashield", bi.DataShield ? "1" : "0");
                if (!string.IsNullOrEmpty(bi.Device)) IniHelper.SetIni("device", bi.Device);
                IniHelper.SetIni("gmp", bi.Gmp ? "1" : "0");
                IniHelper.SetIni("plugin", bi.Plugin ? "1" : "0");
                if (!string.IsNullOrEmpty(bi.Sn)) IniHelper.SetIni("sn", bi.Sn);
                if (!string.IsNullOrEmpty(bi.Type)) IniHelper.SetIni("type", bi.Type);
                IniHelper.SetIni("unit", bi.Unit ? "1" : "0");
                IniHelper.SetIni("autoReport", bi.AutoReport ? "1" : "0");
                if (!string.IsNullOrEmpty(bi.Year)) IniHelper.SetIni("year", bi.Year);
                SetTestId(bi.LastTestId);
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("设置设备的基本信息失败").Write();
                throw new BusinessException(LanguageManager.GetLanguageValue("ActionFail"));
            }

            return 0;
        }

        /// <summary>
        /// 获取试验编号
        /// </summary>
        /// <returns></returns>
        public static int GetTestId()
        {
            try
            {
                var id = int.Parse(IniHelper.GetIni(IdFile, "id", "id", "0"));

                return id;
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("读取试验编号失败").Write();
                return 0;//试验编号大于0
            }
        }

        /// <summary>
        /// 获取试验编号
        /// </summary>
        /// <returns></returns>
        public static int GetNextTestId()
        {
            try
            {
                var id = IniHelper.GetIni(IdFile, "id", "id", "0").ToInt32();
                id++;
                IniHelper.SetIni(IdFile, "id", "id", id + "");
                OnBaseInfoChanged(null);
                return id;
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("读取试验编号失败").Write();
                return 0;//试验编号大于0
            }
        }

        /// <summary>
        /// 设置试验编号
        /// </summary>
        /// <returns></returns>
        public static int SetTestId(int testId)
        {
            if (testId <= 0)
            {
                return -1;
            }
            try
            {
                IniHelper.SetIni(IdFile, "id", "id", testId + "");
                return 0;
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("设置试验编号出错").Write();
                return -1;
            }
        }

        /// <summary>
        /// 获取数据盾配置
        /// </summary>
        /// <returns></returns>
        public static DataShieldInfo GetDataShieldInfo()
        {
            IniHelper.Filename = IniFile;
            IniHelper.SectionName = "datashield";

            return new DataShieldInfo
            {
                Ip = IniHelper.GetIni("ip", "192.168.1.100"),
                Port = IniHelper.GetIni("port", "10000").ToInt32(),
                AutoDelete = IniHelper.GetIni("autodelete", "0").ToInt32(),
            };
        }

        /// <summary>
        /// 获取界面配置
        /// </summary>
        /// <returns></returns>
        public static UiSetting GetUiSetting()
        {
            IniHelper.Filename = IniFile;
            IniHelper.SectionName = "ui";

            return new UiSetting
            {
                ShowTime = IniHelper.GetIni("showTime", "0").ToInt()==1,
                TimeFormat = IniHelper.GetIni("timeFormat", "yyyy-MM-dd HH:mm"),
                ShowReceivedByteCount = IniHelper.GetIni("showReceivedByteCount", "0").ToInt() == 1,
                ShowSentByteCount = IniHelper.GetIni("showSentByteCount", "0").ToInt() == 1,
                ShowZeroToggleButton = IniHelper.GetIni("showZeroToggleButton", "0").ToInt() == 1,
                TitleShowAppName = IniHelper.GetIni("titleShowAppName", "1").ToInt() == 1,
                TitleShowVersion = IniHelper.GetIni("titleShowVersion", "1").ToInt() == 1,
            };
        }

        /// <summary>
        /// 设置数据盾配置信息
        /// </summary>
        /// <param name="dsi"></param>
        /// <returns></returns>
        public static int SetDataShieldInfo(DataShieldInfo dsi)
        {
            IniHelper.Filename = IniFile;
            IniHelper.SectionName = "datashield";

            try
            {
                if (!string.IsNullOrEmpty(dsi.Ip))
                {
                    IniHelper.SetIni("ip", dsi.Ip);
                }

                if (dsi.Port > 0)
                {
                    IniHelper.SetIni("port", dsi.Port + "");
                }

                IniHelper.SetIni("autodelete", dsi.AutoDelete + "");
                return 0;
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("设置数据盾信息出错").Write();
                return -1;
            }
        }

        /// <summary>
        /// 获取数据盾配置
        /// </summary>
        /// <returns></returns>
        public static RemoteInfo GetRemoteInfo()
        {
            IniHelper.Filename = IniFile;
            IniHelper.SectionName = "remote";

            return new RemoteInfo
            {
                Host = IniHelper.GetIni("host", ""),
                Share = IniHelper.GetIni("share", ""),
                User = IniHelper.GetIni("user", ""),
                Password = IniHelper.GetIni("password", ""),
            };
        }

        /// <summary>
        /// 设置远程主机信息
        /// </summary>
        /// <param name="ri"></param>
        /// <returns></returns>
        public static int SetRemoteInfo(RemoteInfo ri)
        {
            IniHelper.Filename = IniFile;
            IniHelper.SectionName = "remote";

            try
            {
                IniHelper.SetIni("host", ri.Host);
                IniHelper.SetIni("share", ri.Share);
                IniHelper.SetIni("user", ri.User);
                IniHelper.SetIni("password", ri.Password);
                return 0;
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("设置远程主机信息出错").Write();
                return -1;
            }
        }

        public static int TestRemote(RemoteInfo ri, out string result, string lid)
        {
            try
            {
                Component.WNetCancelConnection2(ri.Share, 1, true);
                var logsResource = new Component.NetResource
                {
                    LocalName = ri.Share,
                    RemoteName = $@"\\{ri.Host}\{ri.Share}",
                    dwScope = 0,
                    dwUsage = 0,
                    dwDisplayType = 0
                };

                var r = Component.WNetAddConnection3(new IntPtr(0), ref logsResource, ri.Password,
                    ri.User, 0);

                if (r != 0)
                {
                    result = LanguageTool.GetLanguage("SystemSet-RemoteFail", lid);
                    return -1;
                }

                var file = File.Create("test.bat");
                file.Close();
                var target = $@"\\{ri.Host}\{ri.Share}\{"test.bat"}";
                try
                {
                    if (File.Exists(target)) File.Delete(target);
                    File.Move("test.bat", target);
                }
                catch
                {
                    result = LanguageTool.GetLanguage("SystemSet-RemoteNoPermission", lid);
                    return -1;
                }
                result = LanguageTool.GetLanguage("SystemSet-RemoteSuccess", lid);
                return 0;
            }
            catch (Exception)
            {
                result = LanguageTool.GetLanguage("SystemSet-RemoteFail", lid);
                return -1;
            }
            finally
            {
                Component.WNetCancelConnection2(ri.Share, 1, true);
            }
        }

        /// <summary>
        /// 获取磁盘配置信息
        /// </summary>
        /// <returns></returns>
        public static DiskInfo GetDiskInfo()
        {
            var di = new DiskInfo();
            try
            {
                di.AutoDelete = IniHelper.GetIni(IniFile, "disk", "autodelete", "0") != "0";
                di.Capacity = IniHelper.GetIni(IniFile, "disk", "capacity", "1024").ToDouble();
                di.Month = IniHelper.GetIni(IniFile, "disk", "month", "6").ToInt32();
                var dt = IniHelper.GetIni(IniFile, "diskrecord", "time", "");
                di.Time = string.IsNullOrEmpty(dt) ? DateTime.MinValue : dt.ToDateTime();
                di.Total = IniHelper.GetIni(IniFile, "diskrecord", "total", "-1").ToDouble();
                di.Unused = IniHelper.GetIni(IniFile, "diskrecord", "unused", "-1").ToDouble();
                di.Used = IniHelper.GetIni(IniFile, "diskrecord", "used", "-1").ToDouble();
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("获取磁盘配置信息出错").Write();
            }

            return di;
        }

        /// <summary>
        /// 设置磁盘配置信息
        /// </summary>
        /// <param name="di"></param>
        /// <returns></returns>
        public static int SetDiskInfo(DiskInfo di)
        {
            IniHelper.Filename = IniFile;
            IniHelper.SectionName = "disk";

            try
            {
                if (di.Capacity > 0)
                {
                    IniHelper.SetIni("capacity", "" + di.Capacity);
                }

                if (di.Month > 0)
                {
                    IniHelper.SetIni("month", "" + di.Month);
                }

                IniHelper.SetIni("autodelete", di.AutoDelete ? "1" : "0");
                return 0;
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("设置磁盘配置信息失败").Write();
                return -1;
            }
        }

        /// <summary>
        /// 获取GMP配置信息
        /// </summary>
        /// <returns></returns>
        public static GmpInfo GetGmpInfo()
        {
            return new GmpInfo
            {
                Sign = IniHelper.GetIni(IniFile, "gmp", "sign", "0") != "0"
            };
        }

        /// <summary>
        /// 设置GMP配置信息
        /// </summary>
        /// <param name="gi"></param>
        /// <returns></returns>
        public static int SetGmpInfo(GmpInfo gi)
        {
            try
            {
                IniHelper.SetIni(IniFile, "gmp", "sign", gi.Sign ? "1" : "0");
                return 0;
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("设置GMP配置信息出错").Write();
                throw new BusinessException(LanguageManager.GetLanguageValue("ActionFail"));
            }
        }

        /// <summary>
        /// 获取安全配置信息
        /// </summary>
        /// <returns></returns>
        public static SafeInfo GetSafeInfo()
        {
            IniHelper.Filename = IniFile;
            IniHelper.SectionName = "safe";

            var si = new SafeInfo();
            try
            {
                si.DefaultPassword = IniHelper.GetIni("defaultPwd", "123qwe");
                si.Expires = IniHelper.GetIni("expires", "30").ToInt32();
                si.Complexity = IniHelper.GetIni("pwdComplexity", "").ToInt32();
                si.PwdMinLength = IniHelper.GetIni("pwdMinLength", "6").ToInt32();
                si.LockCount = IniHelper.GetIni("lockCount", "5").ToInt32();
                si.LockTime = IniHelper.GetIni("lockTime", "120").ToInt32();
                si.ResetTime = IniHelper.GetIni("resetTime", "30").ToInt32();
                si.AccountLockTime = IniHelper.GetIni("accountLockTime", "0").ToInt32();
                si.PasswordHistory = IniHelper.GetIni("passwordHistory", "0").ToInt32();
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("获取安全配置信息失败").Write();
            }

            return si;
        }

        /// <summary>
        /// 设置安全配置信息
        /// </summary>
        /// <param name="si"></param>
        /// <returns></returns>
        public static int SetSafeInfo(SafeInfo si)
        {
            IniHelper.Filename = IniFile;
            IniHelper.SectionName = "safe";

            try
            {
                if (!string.IsNullOrEmpty(si.DefaultPassword))
                {
                    IniHelper.SetIni("defaultPwd", si.DefaultPassword);
                }

                if (si.Complexity > 0)
                {
                    IniHelper.SetIni("pwdComplexity", si.Complexity + "");
                }

                if (si.Expires > 0)
                {
                    IniHelper.SetIni("expires", si.Expires + "");
                }

                if (si.PwdMinLength > 0)
                {
                    IniHelper.SetIni("pwdMinLength", si.PwdMinLength + "");
                }

                if (si.LockCount > 0)
                {
                    IniHelper.SetIni("lockCount", si.LockCount + "");
                }

                if (si.LockTime > 0)
                {
                    IniHelper.SetIni("lockTime", si.LockTime + "");
                }

                if (si.ResetTime > 0)
                {
                    IniHelper.SetIni("resetTime", si.ResetTime + "");
                }

                IniHelper.SetIni("accountLockTime", si.AccountLockTime + "");
                IniHelper.SetIni("passwordHistory", si.PasswordHistory + "");

                return 0;
            }
            catch (Exception e)
            {
                Log.Error().Exception(e).Message("设置安全配置信息失败").Write();
                throw new BusinessException(LanguageManager.GetLanguageValue("ActionFail"));
            }
        }

        /// <summary>
        /// 设置IP地址
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static int SetIpAddress(Ip ip)
        {
            var r = IpHelper.SetDhcpStatus(1, ip.EnableDhcp);
            if (!r) return -1;
            if (ip.EnableDhcp)
            {
                IpHelper.ApplyIpAddress(1);
                var nd = IpHelper.GetDhcpStatus(1) == "1";
                return (nd == ip.EnableDhcp ? 0 : -1);
            }

            r = IpHelper.SetIpAddress(1, ip.IpAddress.Replace(" ", ""));
            if (!r) return -1;
            r = IpHelper.SetSubnetMask(1, ip.Subnetmask.Replace(" ", ""));
            if (!r) return -1;

            r = IpHelper.SetGateWay(1, ip.DefaultGateway.Replace(" ", ""));
            if (!r) return -1;
            r = IpHelper.ApplyIpAddress(1);
            if (!r) return -1;
            if (ip.IpAddress != IpHelper.GetIpAddress(1)) return -1;
            if (ip.DefaultGateway != IpHelper.GetGateWay(1)) return -1;
            if (ip.Subnetmask != IpHelper.GetSubnetMask(1)) return -1;
            return 0;
        }

        /// <summary>
        /// 获取IP地址
        /// </summary>
        /// <returns></returns>
        public static Ip GetIpAddress()
        {
            return new Ip
            {
                EnableDhcp = IpHelper.GetDhcpStatus(1) == "1",
                DefaultGateway = IpHelper.GetGateWay(1),
                IpAddress = IpHelper.GetIpAddress(1),
                Subnetmask = IpHelper.GetSubnetMask(1)
            };
        }

        /// <summary>
        /// 添加单位体系，包括模板数据库和转换回标准单位的转换关系
        /// </summary>
        /// <param name="isOverwrite"></param>
        /// <param name="zipFilename">添加的单位体系文件名，设置用以上位机获取</param>
        /// <returns>-4:已经存在,-3:文件不存在，-2:没有U盘，-1：失败，1：成功</returns>
        public static int AddUnit(bool isOverwrite, out string zipFilename)
        {
            var hn = Setting.GetUsbDisks().FirstOrDefault();
            if (string.IsNullOrEmpty(hn))
            {
                zipFilename = "";
                return -2;
            }

            var zipPath = Path.Combine(hn, UnitDir);
            if (!Directory.Exists(zipPath))
            {
                zipFilename = "";
                return -3;
            }

            // 第一个文件
            var fn = Directory.GetFiles(zipPath).FirstOrDefault();
            if (string.IsNullOrEmpty(fn))
            {
                zipFilename = "";
                return -3;
            }

            bool isExist = false;

            string zipFileName = Path.GetFileNameWithoutExtension(fn);

            //先判断是否存在该单位体系
            if (Directory.Exists(Path.Combine(UnitPath, zipFileName)))
            {
                isExist = true;
                if (!isOverwrite)
                {
                    zipFilename = "";
                    return -4;
                }
            }

            ZipTool.UnZip(fn, UnitPath, "labthink-staff");

            //如果不存在, 插入数据库
            if (!isExist)
            {
                string strSql = "Insert into Units(UnitCode,UnitName,IsDefault) Values(@UnitCode,@UnitName,@IsDefault)";
                zipFilename = fn;
                return SqliteHelper.ExecuteNonQuery(UnitDb, strSql, new object[] { zipFileName, zipFileName, 0 });
            }

            zipFilename = "";
            return 1;
        }

        public static int AddUnit(string file, out string nf)
        {
            bool isExist = false;
            nf = string.Empty;
            string zipFileName = Path.GetFileNameWithoutExtension(file);

            //先判断是否存在该单位体系
            if (Directory.Exists(Path.Combine(UnitPath, zipFileName)))
            {
                return -4;
            }

            ZipTool.UnZip(file, UnitPath, "labthink-staff");

            //如果不存在, 插入数据库
            if (!isExist)
            {
                string strSql = "Insert into Units(UnitCode,UnitName,IsDefault) Values(@UnitCode,@UnitName,@IsDefault)";
                return SqliteHelper.ExecuteNonQuery(UnitDb, strSql, zipFileName, zipFileName, 0);
            }

            return 1;
        }

        /// <summary>
        /// 删除单位体系，包括数据库和模板
        /// </summary>
        /// <param name="code"></param>
        /// <param name="isDefault"></param>
        /// <returns>-1：失败，正：成功，正常返回1</returns>
        public static int RemoveUnit(string code, bool isDefault)
        {
            Log.Debug().Message("删除单位体系").Write();
            using var con = new SQLiteConnection(SqliteHelper.CreateConnectionString(UnitDb));
            con.Open();
            var tran = con.BeginTransaction();
            try
            {
                SqliteHelper.ExecuteNonQuery(tran, "DELETE FROM Units WHERE UnitCode=@UnitCode", code);
                if (isDefault)
                {
                    SqliteHelper.ExecuteNonQuery(tran, "UPDATE Units SET IsDefault=1 WHERE UnitCode=@UnitCode", code);
                }

                Directory.Delete(Path.Combine(UnitPath, code), true);
                tran.Commit();
                return 1;
            }
            catch (Exception e)
            {
                tran.Rollback();
                Log.Error().Exception(e).Message("删除单位体系 {0} 失败", code).Write();
                return -1;
            }
        }

        /// <summary>
        /// 设置缺省单位体系
        /// </summary>
        /// <param name="code"></param>
        /// <returns>0：失败，1：成功</returns>
        public static int SetDefaultUnit(string code)
        {
            //复位原缺省属性
            using var con = new SQLiteConnection(SqliteHelper.CreateConnectionString(UnitDb));
            con.Open();
            var tran = con.BeginTransaction();
            try
            {
                SqliteHelper.ExecuteNonQuery(tran, "UPDATE Units SET IsDefault=0");
                SqliteHelper.ExecuteNonQuery(tran, "UPDATE Units SET IsDefault=1 WHERE UnitCode=@UnitCode", code);
                tran.Commit();
                return 1;
            }
            catch (Exception e)
            {
                tran.Rollback();
                Log.Error().Exception(e).Message("设置默认单位体系失败").Write();
                return -1;
            }
        }

        /// <summary>
        /// 获取所有单位体系
        /// </summary>
        /// <returns></returns>
        public static List<Units> GetUnits()
        {
            Log.Debug().Message("获取所有单位体系").Write();
            using var con = new SQLiteConnection(SqliteHelper.CreateConnectionString(UnitDb));
            con.Open();
            var cmd = con.CreateCommand();
            var reader = SqliteHelper.ExecuteReader(cmd, "SELECT * FROM Units", null);
            var us = new List<Units>();
            while (reader.Read())
            {
                us.Add(new Units { Id = reader["id"].ToInt32(), UnitCode = reader["UnitCode"].ToString(), UnitName = reader["UnitName"].ToString(), IsDefault = reader["IsDefault"].ToInt32() > 0 });
            }

            reader.Close();
            return us;
        }

        /// <summary>
        /// 获取默认单位体系编码
        /// </summary>
        /// <returns></returns>
        public static string GetDefaultUnit()
        {
            Log.Debug().Message("获取默认单位体系编码").Write();
            var sql = "SELECT COUNT(1) FROM Sqlite_master WHERE [type]='table' AND name='Units'";
            var o = SqliteHelper.ExecuteScalar(UnitDb, sql, null);
            if (o == null || o.ToInt32() == 0)
            {
                Log.Debug().Message("没有找到多单位").Write();
                return string.Empty;
            }

            sql = "SELECT COUNT(1) FROM Units";
            o = SqliteHelper.ExecuteScalar(UnitDb, sql, null);
            if (o == null || o.ToInt32() < 1)
            {
                Log.Debug().Message("没有找到多单位").Write();
                return string.Empty;
            }

            using var con = new SQLiteConnection(SqliteHelper.CreateConnectionString(UnitDb));
            con.Open();
            o = SqliteHelper.ExecuteScalar(UnitDb, "SELECT UnitCode FROM Units where isdefault=1");
            return o.ToString();
        }

        public static string GetDefaultUnitZip(string unit)
        {
            var td = Path.Combine(UnitPath, unit);
            if (!Directory.Exists(td)) return string.Empty;
            var tf = td + ".zip";
            ZipTool.ZipDir(td, tf, "");
            return tf;
        }
    }
}
